/***********************************************************************************
 * 文件名： hc32_adv_timer.c
 * 作者： 刘言
 * 版本： 1
 * 说明：
 * 		HC32系列的高级定时器驱动，功能较多，不断完善中。
 *      中断入口统一定义在 isr.c 中。
 * 修改记录：
 * 	2020/10/26: 初版。 刘言。
***********************************************************************************/

#include "HC32_LyLib.h"
#include "hc32_adv_timer.h"


void HC32TIM4_Init()
{
    M0P_ADTIM4->PERAR = TIM4_CYCLE;             // 计数周期
    
    M0P_ADTIM4->GCMAR = TIM4_CHA_VALUE;             // 通道A比较值
#if (TIM4_CHA_EN_BUFF == 1)
    M0P_ADTIM4->GCMCR = TIM4_CHA_VALUE;             // 通道A比较值的缓存
#endif

    M0P_ADTIM4->GCMBR = TIM4_CHB_VALUE;             // 通道B比较值
#if (TIM4_CHB_EN_BUFF == 1)
    M0P_ADTIM4->GCMDR = TIM4_CHB_VALUE;             // 通道B比较值的缓存
#endif

    M0P_ADTIM4->BCONR = (TIM4_CHA_EN_BUFF << 0)   // 通道A启用缓存
                        |(TIM4_CHB_EN_BUFF << 2); // 通道B启用缓存

    M0P_ADTIM4->PCONR = (TIM4_CHA_MODE << 0)        // 通道A模式
                        |(TIM4_CHA_SL << 1)         // 通道A起始电平
                        |(TIM4_CHA_EL << 2)         // 通道A停止电平
                        |(TIM4_CHA_SELM << 3)       // 通道A起始结束电平模式
                        |(TIM4_CHA_ECA << 4)        // 通道A计数值与比较值相等时，动作
                        |(TIM4_CHA_EPA << 6)        // 通道A计数值与周期值相等时，动作
                        |(TIM4_CHA_EN_PORT << 8)    // 通道A：1-端口使能，0-失能
                        |(TIM4_CHA_BKS << 9)        // 通道A刹车信号源
                        |(TIM4_CHA_BKL << 11)       // 通道A刹车电平
                        |(TIM4_CHB_MODE << 16)      
                        |(TIM4_CHB_SL << 17)
                        |(TIM4_CHB_EL << 18)
                        |(TIM4_CHB_SELM << 19)
                        |(TIM4_CHB_ECA << 20)
                        |(TIM4_CHB_EPA << 22)
                        |(TIM4_CHB_EN_PORT << 24)
                        |(TIM4_CHB_BKS << 25)       // 通道B刹车信号源
                        |(TIM4_CHB_BKL << 27)       // 通道B刹车电平
                        ;

    M0P_ADTIM4->FCONR = (TIM4_CHA_EN_FILT << 0)     // 通道A使能输入滤波
                        |(TIM4_CHA_FILT_CK << 1)    // 通道A滤波采样频率
                        |(TIM4_CHB_EN_FILT << 4)    // 通道B使能输入滤波
                        |(TIM4_CHB_FILT_CK << 5)    // 通道B滤波采样频率
                        ;
    
    M0P_ADTIM4->DTUAR = TIM4_DTUA;                  // 向上计数时的死区时间，GCMBR = GCMAR - DTUAR
    M0P_ADTIM4->DTDAR = TIM4_DTDA;                  // 向下计数时的死区时间，GCMBR = GCMAR - DTDAR
    M0P_ADTIM4->DCONR = (TIM4_DTCEN << 0)           // 死区功能使能
                        |(TIM4_SEPA << 8)           // DTUA和DTDA的值是否自动相等
                        ;

    M0P_ADTIM4->ICONR = (TIM4_EN_INTA << 0)
                        |(TIM4_EN_INTB << 1)
                        |(TIM4_EN_INTOV << 6)
                        |(TIM4_EN_INTUD << 7)
                        |(TIM4_EN_INTDE << 8)
                        ;

#if (TIM4_EN_INTA||TIM4_EN_INTB||TIM4_EN_INTOV||TIM4_EN_INTUD||TIM4_EN_INTDE)
    NVIC_ClearPendingIRQ(ADTIM4_IRQn);        // 清除NVIC中断标志位
    NVIC_SetPriority(ADTIM4_IRQn, 3);         // 优先级 3 （0~3）
    NVIC_EnableIRQ(ADTIM4_IRQn);              // NVIC允许中断
#endif

    M0P_ADTIM4->GCONR = (TIM4_RUN << 0)         // 开始计数
                        |(TIM4_CMODE << 1)       // 计数模式
                        |(TIM4_CDIR << 8)       // 计数方向
                        |(TIM4_CKDIV << 4);      // 时钟分频

    
}




void HC32TIM5_Init()
{
    M0P_ADTIM5->PERAR = TIM5_CYCLE;             // 计数周期
    
    M0P_ADTIM5->GCMAR = TIM5_CHA_VALUE;             // 通道A比较值
#if (TIM5_CHA_EN_BUFF == 1)
    M0P_ADTIM5->GCMCR = TIM5_CHA_VALUE;             // 通道A比较值的缓存
#endif

    M0P_ADTIM5->GCMBR = TIM5_CHB_VALUE;             // 通道B比较值
#if (TIM5_CHB_EN_BUFF == 1)
    M0P_ADTIM5->GCMDR = TIM5_CHB_VALUE;             // 通道B比较值的缓存
#endif

    M0P_ADTIM5->BCONR = (TIM5_CHA_EN_BUFF << 0)   // 通道A启用缓存
                        |(TIM5_CHB_EN_BUFF << 2); // 通道B启用缓存

    M0P_ADTIM5->PCONR = (TIM5_CHA_MODE << 0)        // 通道A模式
                        |(TIM5_CHA_SL << 1)         // 通道A起始电平
                        |(TIM5_CHA_EL << 2)         // 通道A停止电平
                        |(TIM5_CHA_SELM << 3)       // 通道A起始结束电平模式
                        |(TIM5_CHA_ECA << 4)        // 通道A计数值与比较值相等时，动作
                        |(TIM5_CHA_EPA << 6)        // 通道A计数值与周期值相等时，动作
                        |(TIM5_CHA_EN_PORT << 8)    // 通道A：1-端口使能，0-失能
                        |(TIM5_CHA_BKS << 9)        // 通道A刹车信号源
                        |(TIM5_CHA_BKL << 11)       // 通道A刹车电平
                        |(TIM5_CHB_MODE << 16)      
                        |(TIM5_CHB_SL << 17)
                        |(TIM5_CHB_EL << 18)
                        |(TIM5_CHB_SELM << 19)
                        |(TIM5_CHB_ECA << 20)
                        |(TIM5_CHB_EPA << 22)
                        |(TIM5_CHB_EN_PORT << 24)
                        |(TIM5_CHB_BKS << 25)       // 通道B刹车信号源
                        |(TIM5_CHB_BKL << 27)       // 通道B刹车电平
                        ;

    M0P_ADTIM5->FCONR = (TIM5_CHA_EN_FILT << 0)     // 通道A使能输入滤波
                        |(TIM5_CHA_FILT_CK << 1)    // 通道A滤波采样频率
                        |(TIM5_CHB_EN_FILT << 4)    // 通道B使能输入滤波
                        |(TIM5_CHB_FILT_CK << 5)    // 通道B滤波采样频率
                        ;
    
    M0P_ADTIM5->DTUAR = TIM5_DTUA;                  // 向上计数时的死区时间，GCMBR = GCMAR - DTUAR
    M0P_ADTIM5->DTDAR = TIM5_DTDA;                  // 向下计数时的死区时间，GCMBR = GCMAR - DTDAR
    M0P_ADTIM5->DCONR = (TIM5_DTCEN << 0)           // 死区功能使能
                        |(TIM5_SEPA << 8)           // DTUA和DTDA的值是否自动相等
                        ;

    M0P_ADTIM5->ICONR = (TIM5_EN_INTA << 0)
                        |(TIM5_EN_INTB << 1)
                        |(TIM5_EN_INTOV << 6)
                        |(TIM5_EN_INTUD << 7)
                        |(TIM5_EN_INTDE << 8)
                        ;

#if (TIM5_EN_INTA||TIM5_EN_INTB||TIM5_EN_INTOV||TIM5_EN_INTUD||TIM5_EN_INTDE)
    NVIC_ClearPendingIRQ(ADTIM5_IRQn);        // 清除NVIC中断标志位
    NVIC_SetPriority(ADTIM5_IRQn, 3);         // 优先级 3 （0~3）
    NVIC_EnableIRQ(ADTIM5_IRQn);              // NVIC允许中断
#endif

    M0P_ADTIM5->GCONR = (TIM5_RUN << 0)         // 开始计数
                        |(TIM5_CMODE << 1)       // 计数模式
                        |(TIM5_CDIR << 8)       // 计数方向
                        |(TIM5_CKDIV << 4);      // 时钟分频
}







void HC32TIM6_Init()
{
    M0P_ADTIM6->PERAR = TIM6_CYCLE;             // 计数周期
    
    M0P_ADTIM6->GCMAR = TIM6_CHA_VALUE;             // 通道A比较值
#if (TIM6_CHA_EN_BUFF == 1)
    M0P_ADTIM6->GCMCR = TIM6_CHA_VALUE;             // 通道A比较值的缓存
#endif

    M0P_ADTIM6->GCMBR = TIM6_CHB_VALUE;             // 通道B比较值
#if (TIM6_CHB_EN_BUFF == 1)
    M0P_ADTIM6->GCMDR = TIM6_CHB_VALUE;             // 通道B比较值的缓存
#endif

    M0P_ADTIM6->BCONR = (TIM6_CHA_EN_BUFF << 0)   // 通道A启用缓存
                        |(TIM6_CHB_EN_BUFF << 2); // 通道B启用缓存

    M0P_ADTIM6->PCONR = (TIM6_CHA_MODE << 0)        // 通道A模式
                        |(TIM6_CHA_SL << 1)         // 通道A起始电平
                        |(TIM6_CHA_EL << 2)         // 通道A停止电平
                        |(TIM6_CHA_SELM << 3)       // 通道A起始结束电平模式
                        |(TIM6_CHA_ECA << 4)        // 通道A计数值与比较值相等时，动作
                        |(TIM6_CHA_EPA << 6)        // 通道A计数值与周期值相等时，动作
                        |(TIM6_CHA_EN_PORT << 8)    // 通道A：1-端口使能，0-失能
                        |(TIM6_CHA_BKS << 9)        // 通道A刹车信号源
                        |(TIM6_CHA_BKL << 11)       // 通道A刹车电平
                        |(TIM6_CHB_MODE << 16)      
                        |(TIM6_CHB_SL << 17)
                        |(TIM6_CHB_EL << 18)
                        |(TIM6_CHB_SELM << 19)
                        |(TIM6_CHB_ECA << 20)
                        |(TIM6_CHB_EPA << 22)
                        |(TIM6_CHB_EN_PORT << 24)
                        |(TIM6_CHB_BKS << 25)       // 通道B刹车信号源
                        |(TIM6_CHB_BKL << 27)       // 通道B刹车电平
                        ;

    M0P_ADTIM6->FCONR = (TIM6_CHA_EN_FILT << 0)     // 通道A使能输入滤波
                        |(TIM6_CHA_FILT_CK << 1)    // 通道A滤波采样频率
                        |(TIM6_CHB_EN_FILT << 4)    // 通道B使能输入滤波
                        |(TIM6_CHB_FILT_CK << 5)    // 通道B滤波采样频率
                        ;
    
    M0P_ADTIM6->DTUAR = TIM6_DTUA;                  // 向上计数时的死区时间，GCMBR = GCMAR - DTUAR
    M0P_ADTIM6->DTDAR = TIM6_DTDA;                  // 向下计数时的死区时间，GCMBR = GCMAR - DTDAR
    M0P_ADTIM6->DCONR = (TIM6_DTCEN << 0)           // 死区功能使能
                        |(TIM6_SEPA << 8)           // DTUA和DTDA的值是否自动相等
                        ;

    M0P_ADTIM6->ICONR = (TIM6_EN_INTA << 0)
                        |(TIM6_EN_INTB << 1)
                        |(TIM6_EN_INTOV << 6)
                        |(TIM6_EN_INTUD << 7)
                        |(TIM6_EN_INTDE << 8)
                        ;

#if (TIM6_EN_INTA||TIM6_EN_INTB||TIM6_EN_INTOV||TIM6_EN_INTUD||TIM6_EN_INTDE)
    NVIC_ClearPendingIRQ(ADTIM6_IRQn);        // 清除NVIC中断标志位
    NVIC_SetPriority(ADTIM6_IRQn, 3);         // 优先级 3 （0~3）
    NVIC_EnableIRQ(ADTIM6_IRQn);              // NVIC允许中断
#endif

    M0P_ADTIM6->GCONR = (TIM6_RUN << 0)         // 开始计数
                        |(TIM6_CMODE << 1)       // 计数模式
                        |(TIM6_CDIR << 8)       // 计数方向
                        |(TIM6_CKDIV << 4);      // 时钟分频
}












void HC32ADTIM_SetCompValue(M0P_ADTIM_TypeDef * adtim, int ch, int value)
{
    switch(ch)
    {
        case 0:
        if(adtim->BCONR_f.BENA)adtim->GCMCR = value;
        else adtim->GCMAR = value;
        break;

        case 1:
        if(adtim->BCONR_f.BENB)adtim->GCMDR = value;
        else adtim->GCMBR = value;
        break;
        default : break;
    }
}
